home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / console / svgatext.3 / svgatext / SVGATextMode-1.3 / XFREE / common_hw / IBMRGB.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-01  |  6.4 KB  |  284 lines

  1. /*
  2.  * Copyright 1995 The XFree86 Project, Inc
  3.  *
  4.  * programming the on-chip clock on the IBM RGB52x
  5.  * Harald Koenig <koenig@tat.physik.uni-tuebingen.de>
  6.  */
  7.  
  8. /* $XFree86: xc/programs/Xserver/hw/xfree86/common_hw/IBMRGB.c,v 3.2 1995/07/07 16:04:03 dawes Exp $ */
  9.  
  10. #include "compiler.h"
  11. #define NO_OSLIB_PROTOTYPES
  12. #include "xf86_OSlib.h"
  13.  
  14. #define S3_SERVER
  15. #include "IBMRGB.h" 
  16.  
  17. extern int vgaCRIndex;
  18. extern int vgaCRReg;
  19.  
  20.  
  21. /*
  22.  * s3OutIBMRGBIndReg() and s3InIBMRGBIndReg() are used to access the indirect
  23.  * RGB52x registers only.
  24.  */
  25.  
  26. #if NeedFunctionPrototypes
  27. void s3OutIBMRGBIndReg(unsigned char reg, unsigned char mask, unsigned char data)
  28. #else
  29. void s3OutIBMRGBIndReg(reg, mask, data)
  30. unsigned char reg;
  31. unsigned char mask;
  32. unsigned char data;
  33. #endif
  34. {
  35.    unsigned char tmp, tmp2 = 0x00;
  36.  
  37.    outb(vgaCRIndex, 0x55);
  38.    tmp = inb(vgaCRReg) & 0xFC;
  39.    outb(vgaCRReg, tmp | 0x01);
  40.  
  41.    outb(IBMRGB_INDEX_LOW, reg);
  42.  
  43.    if (mask != 0x00)
  44.       tmp2 = inb(IBMRGB_INDEX_DATA) & mask;
  45.    outb(IBMRGB_INDEX_DATA, tmp2 | data);
  46.    
  47.    outb(vgaCRIndex, 0x55);
  48.    outb(vgaCRReg, tmp);
  49. }
  50.  
  51. #if NeedFunctionPrototypes
  52. unsigned char s3InIBMRGBIndReg(unsigned char reg)
  53. #else
  54. unsigned char s3InIBMRGBIndReg(reg)
  55. unsigned char reg;
  56. #endif
  57. {
  58. volatile   unsigned char tmp, ret;
  59.  
  60.    outb(vgaCRIndex, 0x55);
  61.    tmp = inb(vgaCRReg) & 0xFC;
  62.    outb(vgaCRReg, tmp | 0x01);
  63.  
  64.    outb(IBMRGB_INDEX_LOW, reg);
  65.    ret = inb(IBMRGB_INDEX_DATA);
  66.  
  67.    outb(vgaCRIndex, 0x55);
  68.    outb(vgaCRReg, tmp);
  69.  
  70.    return(ret);
  71. }
  72.  
  73. #if NeedFunctionPrototypes
  74. static void
  75. s3ProgramIBMRGBClock(int clk, unsigned char m, unsigned char n, 
  76.              unsigned char df)
  77. #else
  78. static void
  79. s3ProgramIBMRGBClock(clk, m, n, df)
  80. int clk;
  81. unsigned char m;
  82. unsigned char n;
  83. unsigned char df;
  84. #endif
  85. {
  86.    int tmp;
  87.    tmp = 1;
  88.    s3OutIBMRGBIndReg(IBMRGB_misc_clock, ~1, 1);
  89.  
  90.    s3OutIBMRGBIndReg(IBMRGB_m0+2*clk, 0, (df<<6) | (m&0x3f));
  91.    s3OutIBMRGBIndReg(IBMRGB_n0+2*clk, 0, n);
  92.  
  93.    s3OutIBMRGBIndReg(IBMRGB_pll_ctrl2, 0xf0, clk);
  94.    s3OutIBMRGBIndReg(IBMRGB_pll_ctrl1, 0xf8, 3);
  95. }
  96.  
  97. #if NeedFunctionPrototypes
  98. void IBMRGBSetClock(long freq, int clk, long dacspeed, long fref)
  99. #else
  100. void
  101. IBMRGBSetClock(freq, clk, dacspeed, fref)
  102. long freq;
  103. int clk;
  104. long dacspeed;
  105. long fref;
  106. #endif
  107. {
  108.    volatile   double ffreq,fdacspeed,ffref;
  109.    volatile   int df, n, m, max_n, min_df;
  110.    volatile   int best_m=69, best_n=17, best_df=0;
  111.    volatile   double  diff, mindiff;
  112.    
  113. #define FREQ_MIN   16250  /* 1000 * (0+65) / 4 */
  114. #define FREQ_MAX  dacspeed
  115.  
  116.    if (freq < FREQ_MIN)
  117.       ffreq = FREQ_MIN / 1000.0;
  118.    else if (freq > FREQ_MAX)
  119.       ffreq = FREQ_MAX / 1000.0;
  120.    else
  121.       ffreq = freq / 1000.0;
  122.    
  123.    fdacspeed = dacspeed / 1e3;
  124.    ffref = fref / 1e3;
  125.  
  126.    ffreq /= ffref;
  127.    ffreq *= 16;
  128.    mindiff = ffreq;
  129.  
  130.    if (freq <= dacspeed/4) 
  131.       min_df = 0;
  132.    else if (freq <= dacspeed/2) 
  133.       min_df = 1;
  134.    else 
  135.       min_df = 2;
  136.  
  137.    for(df=0; df<4; df++) {
  138.       ffreq /= 2;
  139.       mindiff /= 2;
  140.       if (df < min_df) continue;
  141.  
  142.       /* the remaining formula is  ffreq = (m+65) / n */
  143.  
  144.       if (df < 3) max_n = fref/1000/2;
  145.       else        max_n = fref/1000;
  146.       if (max_n > 31)  max_n = 31;
  147.       
  148.       for (n=2; n <= max_n; n++) {
  149.      m = (int)(ffreq * n + 0.5) - 65;
  150.      if (m < 0)
  151.         m = 0;
  152.      else if (m > 63) 
  153.         m = 63;
  154.      
  155.      diff = (m+65.0) / n - ffreq;
  156.      if (diff<0)
  157.         diff = -diff;
  158.      
  159.      if (diff < mindiff) {
  160.         mindiff = diff;
  161.         best_n = n;
  162.         best_m = m;
  163.         best_df = df;
  164.      }
  165.       }
  166.    }
  167.  
  168. #ifdef DEBUG
  169.    ErrorF("clk %d, setting to %f, m 0x%02x %d, n 0x%02x %d, df %d\n", clk,
  170.       ((best_m+65.0)/best_n) / (8>>best_df) * ffref,
  171.       best_m, best_m, best_n, best_n, best_df);
  172. #endif
  173.  
  174.    s3ProgramIBMRGBClock(clk, best_m, best_n, best_df);
  175. }
  176.  
  177. int s3IBMRGB_Probe()
  178. {
  179.    unsigned char CR43, CR55, dac[3], lut[6];
  180.    unsigned char ilow, ihigh, id, rev, id2, rev2;
  181.    int i,j;
  182.    int ret=0;
  183.  
  184.    outb(vgaCRIndex, 0x43);
  185.    CR43 = inb(vgaCRReg);
  186.    outb(vgaCRReg, CR43 & ~0x02);
  187.  
  188.    outb(vgaCRIndex, 0x55);
  189.    CR55 = inb(vgaCRReg) ;
  190.    outb(vgaCRReg, CR55 & ~0x03);
  191.  
  192.    /* save DAC and first LUT entries */
  193.    for (i=0; i<3; i++) 
  194.       dac[i] = inb(IBMRGB_PIXEL_MASK+i);
  195.    for (i=j=0; i<2; i++) {
  196.       outb(IBMRGB_READ_ADDR, i);
  197.       lut[j++] = inb(IBMRGB_RAMDAC_DATA);
  198.       lut[j++] = inb(IBMRGB_RAMDAC_DATA);
  199.       lut[j++] = inb(IBMRGB_RAMDAC_DATA);
  200.    }
  201.  
  202.    outb(vgaCRIndex, 0x55);
  203.    outb(vgaCRReg, (CR55 & ~0x03) | 0x01);  /* set RS2 */
  204.  
  205.    /* read ID and revision */
  206.    ilow  = inb(IBMRGB_INDEX_LOW);
  207.    ihigh = inb(IBMRGB_INDEX_HIGH);
  208.    outb(IBMRGB_INDEX_HIGH, 0);  /* index high */
  209.    outb(IBMRGB_INDEX_LOW, IBMRGB_rev);
  210.    rev = inb(IBMRGB_INDEX_DATA);
  211.    outb(IBMRGB_INDEX_LOW, IBMRGB_id);
  212.    id  = inb(IBMRGB_INDEX_DATA);
  213.  
  214.    /* known IDs:  
  215.       1 = RGB525
  216.       2 = RGB524, RGB528 
  217.       */
  218.       
  219.    if (id >= 1 && id <= 2) { 
  220.       /* check if ID and revision are read only */
  221.       outb(IBMRGB_INDEX_LOW, IBMRGB_rev);
  222.       outb(IBMRGB_INDEX_DATA, ~rev);
  223.       outb(IBMRGB_INDEX_LOW, IBMRGB_id);
  224.       outb(IBMRGB_INDEX_DATA, ~id);
  225.       outb(IBMRGB_INDEX_LOW, IBMRGB_rev);
  226.       rev2 = inb(IBMRGB_INDEX_DATA);
  227.       outb(IBMRGB_INDEX_LOW, IBMRGB_id);
  228.       id2  = inb(IBMRGB_INDEX_DATA);
  229.       
  230.       if (id == id2 && rev == rev2) {  /* IBM RGB52x found */
  231.      ret = (id<<8) | rev;
  232.       }
  233.       else {
  234.      outb(IBMRGB_INDEX_LOW, IBMRGB_rev);
  235.      outb(IBMRGB_INDEX_DATA, rev);
  236.      outb(IBMRGB_INDEX_LOW, IBMRGB_id);
  237.      outb(IBMRGB_INDEX_DATA, id);
  238.       }
  239.    }   
  240.    outb(IBMRGB_INDEX_LOW,  ilow);
  241.    outb(IBMRGB_INDEX_HIGH, ihigh);
  242.  
  243.    outb(vgaCRIndex, 0x55);
  244.    outb(vgaCRReg, CR55 & ~0x03);  /* reset RS2 */
  245.  
  246.    /* restore DAC and first LUT entries */
  247.    for (i=j=0; i<2; i++) {
  248.       outb(IBMRGB_WRITE_ADDR, i);
  249.       outb(IBMRGB_RAMDAC_DATA, lut[j++]);
  250.       outb(IBMRGB_RAMDAC_DATA ,lut[j++]);
  251.       outb(IBMRGB_RAMDAC_DATA ,lut[j++]);
  252.    }
  253.    for (i=0; i<3; i++) 
  254.       outb(IBMRGB_PIXEL_MASK+i, dac[i]);
  255.    
  256.    outb(vgaCRIndex, 0x43);
  257.    outb(vgaCRReg, CR43);
  258.    outb(vgaCRIndex, 0x55);
  259.    outb(vgaCRReg, CR55);   
  260.  
  261.    return ret;
  262. }
  263.  
  264.  
  265. void s3IBMRGB_Init()
  266. {
  267.    unsigned char CR55, tmp;
  268.  
  269.    outb(vgaCRIndex, 0x43);
  270.    tmp = inb(vgaCRReg);
  271.    outb(vgaCRReg, tmp & ~0x02);
  272.  
  273.    outb(vgaCRIndex, 0x55);
  274.    CR55 = inb(vgaCRReg) ;
  275.    outb(vgaCRReg, (CR55 & ~0x03) | 0x01);  /* set RS2 */
  276.  
  277.    tmp = inb(IBMRGB_INDEX_CONTROL);
  278.    outb(IBMRGB_INDEX_CONTROL, tmp & ~1);  /* turn off auto-increment */
  279.    outb(IBMRGB_INDEX_HIGH, 0);        /* index high byte */
  280.  
  281.    outb(vgaCRIndex, 0x55);
  282.    outb(vgaCRReg, CR55 & ~0x03);  /* reset RS2 */
  283. }
  284.